<script setup>
import { ref, reactive, onMounted } from 'vue';
import { listProduct } from '@/api/product/product';
import { getDicts } from "@/api/system/dict/data";
import config from "@/config";
import { onLoad } from "@dcloudio/uni-app";

const tabbar = ref([]); // 分类数据
const scrollTop = ref(0); // tab标题的滚动条位置
const current = ref(0); // 预设当前项的值
const menuHeight = ref(0); // 左边菜单的高度
const menuItemHeight = ref(0); // 左边菜单item的高度
const productCategoryOptions = ref([]); // 商品分类字典
const productStatusOptions = ref([]); // 商品状态字典
const loading = ref(true);

// 查询参数
const queryParams = ref({
  pageNum: 1,
  pageSize: 10,
  productName: null,
  productCategory: null,
  productStatus: null,
});

// 搜索关键词
const searchKeyword = ref('');

// 获取字典数据
const getDictData = () => {
  getDicts('product_type').then(response => {
    productCategoryOptions.value = [];
    for (let opt of response.data) {
      productCategoryOptions.value.push({
        text: opt.dictLabel,
        value: opt.dictValue
      });
    }
  });

  getDicts('product_status').then(response => {
    productStatusOptions.value = [];
    for (let opt of response.data) {
      productStatusOptions.value.push({
        text: opt.dictLabel,
        value: opt.dictValue
      });
    }
  });
};

// 获取商品列表
const getProductList = async () => {
  try {
    loading.value = true;
    const res = await listProduct(queryParams.value);

    if (res.code === 200) {
      // 处理商品数据，按分类分组
      const categories = {};

      // 获取商品数据
      let productData = [];
      if (res.data) {
        productData = Array.isArray(res.data) ? res.data : [];
      } else if (res.rows) {
        productData = Array.isArray(res.rows) ? res.rows : [];
      }

      if (productData.length === 0) {
        tabbar.value = [];
        return;
      }

      productData.forEach(item => {
        // 获取分类名称
        let categoryName = '未分类';
        if (item.productCategory) {
          const categoryOption = productCategoryOptions.value.find(
              opt => opt.value === item.productCategory
          );
          categoryName = categoryOption ? categoryOption.text : item.productCategory;
        }

        if (!categories[categoryName]) {
          categories[categoryName] = {
            name: categoryName,
            foods: []
          };
        }

        categories[categoryName].foods.push({
          id: item.id,
          name: item.productName,
          icon: addBaseUrl(item.productImage),
          price: item.pointsPrice,
          originalPrice: item.originalPrice,
          stock: item.stockQuantity,
          sold: item.soldQuantity,
          status: item.productStatus,
          category: item.productCategory,
          brand: item.productBrand,
          description: item.productDescription,
          exchangeLimit: item.exchangeLimit,
          hasExchangeLimit: item.hasExchangeLimit,
          startTime: item.startTime,
          endTime: item.endTime
        });
      });

      tabbar.value = Object.values(categories);
    } else {
      uni.showToast({
        title: res.msg || '获取商品列表失败',
        icon: 'none'
      });
    }
  } catch (error) {
    uni.showToast({
      title: '获取商品列表失败',
      icon: 'none'
    });
  } finally {
    loading.value = false;
  }
};

// 获取字典标签
const getDictLabel = (dictOptions, value) => {
  if (!value || !dictOptions || !dictOptions.length) return value;
  const option = dictOptions.find(item => String(item.value) === String(value));
  return option ? option.label : value;
};

// 添加基础URL
const addBaseUrl = (url) => {
  if (!url) return '';
  // 如果URL已经包含http或https，直接返回
  if (url.startsWith('http://') || url.startsWith('https://')) {
    return url;
  }
  // 如果是字符串，先尝试分割
  if (typeof url === 'string') {
    const urls = url.split(',');
    if (urls.length > 1) {
      return urls.map(item => {
        // 如果单个URL已经包含http或https，直接返回
        if (item.startsWith('http://') || item.startsWith('https://')) {
          return item;
        }
        return config.baseUrl + item;
      });
    }
    return config.baseUrl + url;
  }
  // 如果是数组
  if (Array.isArray(url)) {
    return url.map(item => {
      // 如果单个URL已经包含http或https，直接返回
      if (item.startsWith('http://') || item.startsWith('https://')) {
        return item;
      }
      return config.baseUrl + item;
    });
  }
  return '';
};

// 获取一个目标元素的高度
const getElRect = (elClass, dataVal) => {
  return new Promise((resolve) => {
    const query = uni.createSelectorQuery();
    query.select('.' + elClass).boundingClientRect(data => {
      if (!data) {
        setTimeout(() => {
          getElRect(elClass, dataVal);
        }, 10);
        return;
      }
      if (dataVal === 'menuHeight') {
        menuHeight.value = data.height;
      } else if (dataVal === 'menuItemHeight') {
        menuItemHeight.value = data.height;
      }
      resolve();
    }).exec();
  });
};

// 点击左边的栏目切换
const swichMenu = async (index) => {
  if (index === current.value) return;
  current.value = index;

  // 如果为0，意味着尚未初始化
  if (menuHeight.value === 0 || menuItemHeight.value === 0) {
    try {
      await getElRect('menu-scroll-view', 'menuHeight');
      await getElRect('u-tab-item', 'menuItemHeight');
    } catch (error) {
      console.error('获取元素高度失败:', error);
      return;
    }
  }

  // 将菜单菜单活动item垂直居中
  scrollTop.value = index * menuItemHeight.value + menuItemHeight.value / 2 - menuHeight.value / 2;
};

// 初始化菜单高度
const initMenuHeight = async () => {
  try {
    await getElRect('menu-scroll-view', 'menuHeight');
    await getElRect('u-tab-item', 'menuItemHeight');
  } catch (error) {
    console.error('初始化菜单高度失败:', error);
  }
};

// 点击商品
const clickMenu = (product) => {
  uni.navigateTo({
    url: `/pages/mallMenu/detail?id=${product.id}`
  });
};

// 处理图片加载错误
const handleImageError = (e) => {
  e.target.src = '/static/images/default.png';
};

// 搜索商品
const handleSearch = () => {
  queryParams.value.productName = searchKeyword.value;
  queryParams.value.pageNum = 1; // 重置页码
  getProductList();
};

// 清空搜索
const clearSearch = () => {
  searchKeyword.value = '';
  queryParams.value.productName = null;
  getProductList();
};

onLoad(() => {
  getDictData();
  getProductList();
  // 初始化菜单高度
  setTimeout(() => {
    initMenuHeight();
  }, 100);
});
</script>

<template>
  <view class="u-wrap">
    <!-- 搜索框区域 -->
    <view class="u-search-box">
      <view class="u-search-inner">
        <view class="search-icon">
          <u-icon name="search" color="#8B5CF6" :size="32"></u-icon>
        </view>
        <input
            class="u-search-input"
            v-model="searchKeyword"
            placeholder="搜索您心仪的商品..."
            confirm-type="search"
            @confirm="handleSearch"
        />
        <view v-if="searchKeyword" class="clear-icon" @click="clearSearch">
          <u-icon name="close-circle-fill" color="#E5E7EB" :size="32"></u-icon>
        </view>
      </view>
    </view>

    <!-- 主体内容区域 -->
    <view class="u-menu-wrap">
      <!-- 左侧分类菜单 -->
      <scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
        <view v-for="(item, index) in tabbar" :key="index" class="u-tab-item"
              :class="[current == index ? 'u-tab-item-active' : '']" :data-current="index"
              @tap.stop="swichMenu(index)">
          <view class="tab-content">
            <text class="tab-text">{{ item.name }}</text>
            <view v-if="current == index" class="tab-indicator"></view>
          </view>
        </view>
      </scroll-view>

      <!-- 右侧商品内容区域 -->
      <view class="u-menu-content">
        <block v-for="(item, index) in tabbar" :key="index">
          <scroll-view scroll-y class="right-box" v-if="current == index">
            <view class="page-view">
              <view class="class-item">
                <view class="item-title">
                  <view class="title-decoration"></view>
                  <text class="title-text">{{ item.name }}</text>
                  <view class="title-badge">{{ item.foods.length }}</view>
                </view>
                <view class="item-container">
                  <view class="product-card" v-for="(item1, index1) in item.foods" :key="index1"
                        @click="clickMenu(item1)">
                    <view class="card-image-wrapper">
                      <image class="card-image" :src="Array.isArray(item1.icon) ? item1.icon[0] : item1.icon" mode="aspectFill" @error="handleImageError"></image>
                      <view v-if="item1.hasExchangeLimit" class="limit-badge">
                        <text class="limit-text">限制</text>
                      </view>
                    </view>
                    <view class="card-content">
                      <view class="product-name">{{ item1.name }}</view>
                      <view class="price-section">
                        <text class="current-price">¥{{ item1.price }}</text>
                        <text class="original-price" v-if="item1.originalPrice">¥{{ item1.originalPrice }}</text>
                      </view>
                      <view class="product-stats">
                        <view class="stat-item">
                          <text class="stat-label">已售</text>
                          <text class="stat-value">{{ item1.sold }}</text>
                        </view>
                        <view class="stat-item">
                          <text class="stat-label">限兑</text>
                          <text class="stat-value orange">{{ item1.exchangeLimit }}</text>
                        </view>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </scroll-view>
        </block>
      </view>
    </view>
    <u-loading-page :loading="loading"></u-loading-page>
  </view>
</template>

<style lang="scss" scoped>
.u-wrap {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.u-search-box {
  padding: 20rpx 24rpx;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.u-search-inner {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  border-radius: 30rpx;
  display: flex;
  align-items: center;
  padding: 16rpx 24rpx;
  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
  transition: all 0.3s ease;

  &:focus-within {
    transform: translateY(-1rpx);
    box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.12);
  }
}

.search-icon, .clear-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.clear-icon {
  transition: transform 0.2s ease;
  &:active {
    transform: scale(0.9);
  }
}

.u-search-input {
  flex: 1;
  font-size: 26rpx;
  color: #374151;
  margin: 0 16rpx;
  height: 50rpx;
  background: transparent;
  border: none;
  outline: none;

  &::placeholder {
    color: #9CA3AF;
    font-weight: 400;
  }
}

.u-menu-wrap {
  flex: 1;
  display: flex;
  overflow: hidden;
  height: 0;
  background: #F8FAFC;
}

.u-tab-view {
  width: 160rpx;
  height: 100%;
  flex-shrink: 0;
  background: #FFFFFF;
  box-shadow: 2rpx 0 16rpx rgba(0, 0, 0, 0.04);
}

.u-tab-item {
  height: 90rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;

  &:hover {
    background: rgba(139, 92, 246, 0.05);
  }
}

.u-tab-item-active {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(167, 139, 250, 0.1) 100%);

  .tab-text {
    color: #8B5CF6;
    font-weight: 600;
    font-size: 26rpx;
    transform: translateX(6rpx);
  }
}

.tab-content {
  display: flex;
  align-items: center;
  position: relative;
  width: 100%;
  justify-content: center;
}

.tab-text {
  font-size: 24rpx;
  color: #6B7280;
  font-weight: 500;
  transition: all 0.3s ease;
  text-align: center;
  line-height: 1.3;
  padding: 0 8rpx;
}

.tab-indicator {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 6rpx;
  height: 40rpx;
  background: linear-gradient(135deg, #8B5CF6 0%, #A78BFA 100%);
  border-radius: 0 6rpx 6rpx 0;
  animation: slideIn 0.3s ease;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-50%) translateX(-10rpx);
  }
  to {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
  }
}

.u-menu-content {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.right-box {
  background: #F8FAFC;
  height: 100%;
}

.page-view {
  padding: 24rpx;
}

.class-item {
  background: #FFFFFF;
  border-radius: 20rpx;
  padding: 30rpx 24rpx;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.8);
}

.item-title {
  display: flex;
  align-items: center;
  margin-bottom: 30rpx;
  position: relative;
}

.title-decoration {
  width: 6rpx;
  height: 32rpx;
  background: linear-gradient(135deg, #8B5CF6 0%, #A78BFA 100%);
  border-radius: 3rpx;
  margin-right: 16rpx;
}

.title-text {
  font-size: 32rpx;
  color: #1F2937;
  font-weight: 700;
  flex: 1;
}

.title-badge {
  background: linear-gradient(135deg, #8B5CF6 0%, #A78BFA 100%);
  color: white;
  font-size: 22rpx;
  font-weight: 600;
  padding: 6rpx 12rpx;
  border-radius: 16rpx;
  min-width: 32rpx;
  text-align: center;
}

.item-container {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx;
  justify-content: flex-start;
}

.product-card {
  width: calc(33.333% - 11rpx);
  min-width: 220rpx;
  background: #FFFFFF;
  border-radius: 14rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(243, 244, 246, 0.8);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  display: flex;
  flex-direction: column;

  &:hover {
    transform: translateY(-3rpx);
    box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
  }

  &:active {
    transform: translateY(-1rpx);
  }
}

.card-image-wrapper {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 160rpx;
  flex-shrink: 0;
}

.card-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.product-card:hover .card-image {
  transform: scale(1.02);
}

.limit-badge {
  position: absolute;
  top: 8rpx;
  right: 8rpx;
  background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
  border-radius: 6rpx;
  padding: 3rpx 6rpx;
  box-shadow: 0 2rpx 6rpx rgba(239, 68, 68, 0.3);
}

.limit-text {
  color: white;
  font-size: 16rpx;
  font-weight: 600;
}

.card-content {
  padding: 16rpx;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 130rpx;
}

.product-name {
  font-size: 24rpx;
  color: #1F2937;
  font-weight: 600;
  margin-bottom: 10rpx;
  line-height: 1.3;
  height: 56rpx;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.price-section {
  display: flex;
  align-items: baseline;
  margin-bottom: 10rpx;
  gap: 6rpx;
  flex-wrap: wrap;
}

.current-price {
  color: #EF4444;
  font-size: 24rpx;
  font-weight: 700;
}

.original-price {
  color: #9CA3AF;
  font-size: 20rpx;
  text-decoration: line-through;
  font-weight: 500;
}

.product-stats {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: auto;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 0;
}

.stat-label {
  color: #6B7280;
  font-size: 18rpx;
  font-weight: 500;
  margin-bottom: 2rpx;
}

.stat-value {
  color: #374151;
  font-size: 20rpx;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 80rpx;

  &.orange {
    color: #F59E0B;
  }
}

/* 响应式适配 */
@media screen and (max-width: 750rpx) {
  .u-tab-view {
    width: 140rpx;
  }

  .item-container {
    justify-content: flex-start;
  }

  .product-card {
    width: calc(50% - 8rpx);
    min-width: 200rpx;
  }

  .card-image-wrapper {
    height: 140rpx;
  }

  .card-content {
    padding: 14rpx;
    min-height: 120rpx;
  }

  .product-name {
    font-size: 22rpx;
    height: 50rpx;
  }

  .current-price {
    font-size: 22rpx;
  }

  .stat-label {
    font-size: 16rpx;
  }

  .stat-value {
    font-size: 18rpx;
    max-width: 60rpx;
  }

  .tab-text {
    font-size: 22rpx;
  }
}

@media screen and (max-width: 480rpx) {
  .product-card {
    width: 100%;
    max-width: 300rpx;
  }
}

/* 加载动画 */
@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

.loading {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
</style>
